"""
MySQL到KWDB转换器测试
"""

import unittest
from src.parser import MySQLParser, ParsedStatement, StatementType
from src.converter import MySQLToKWDBConverter


class TestMySQLToKWDBConverter(unittest.TestCase):
    """MySQL到KWDB转换器测试类"""
    
    def setUp(self):
        """测试前准备"""
        self.converter = MySQLToKWDBConverter()
    
    def test_data_type_conversion(self):
        """测试数据类型转换"""
        sql = "CREATE TABLE test (id INT AUTO_INCREMENT, name VARCHAR(100), created DATETIME);"
        
        # 创建模拟的解析语句
        stmt = ParsedStatement(
            statement_type=StatementType.CREATE_TABLE,
            original_sql=sql,
            parsed_sql=None,
            table_name="test"
        )
        
        converted_stmt = self.converter.convert_statement(stmt)
        converted_sql = converted_stmt.original_sql
        
        # 检查数据类型转换
        self.assertIn('STRING', converted_sql)  # VARCHAR -> STRING
        self.assertIn('TIMESTAMP', converted_sql)  # DATETIME -> TIMESTAMP
        self.assertIn('DEFAULT unique_rowid()', converted_sql)  # AUTO_INCREMENT
    
    def test_syntax_rules_application(self):
        """测试语法规则应用"""
        sql = "CREATE TABLE `test` (id INT AUTO_INCREMENT) ENGINE=InnoDB DEFAULT CHARSET=utf8;"
        
        converted_sql = self.converter._apply_syntax_rules(sql)
        
        # 检查语法转换
        self.assertNotIn('ENGINE=InnoDB', converted_sql)
        self.assertNotIn('DEFAULT CHARSET=utf8', converted_sql)
        self.assertNotIn('`', converted_sql)  # 反引号应该被移除
        self.assertIn('DEFAULT unique_rowid()', converted_sql)
    
    def test_remove_backticks(self):
        """测试移除反引号"""
        sql = "CREATE TABLE `users` (`id` INT, `name` VARCHAR(100));"
        
        converted_sql = self.converter._apply_syntax_rules(sql)
        
        self.assertNotIn('`', converted_sql)
        self.assertIn('users', converted_sql)
        self.assertIn('id', converted_sql)
        self.assertIn('name', converted_sql)
    
    def test_tinyint_to_bool_conversion(self):
        """测试TINYINT(1)到BOOL的转换"""
        sql = "CREATE TABLE test (active TINYINT(1), status TINYINT(4));"
        
        converted_sql = self.converter._apply_syntax_rules(sql)
        
        # TINYINT(1)应该转换为BOOL
        self.assertIn('BOOL', converted_sql)
        # TINYINT(4)应该保持为TINYINT或转换为INT
        self.assertTrue('TINYINT(4)' in converted_sql or 'INT' in converted_sql)
    
    def test_convert_create_table_statement(self):
        """测试转换CREATE TABLE语句"""
        sql = """
        CREATE TABLE `users` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `name` varchar(100) NOT NULL,
            `active` tinyint(1) DEFAULT 0,
            PRIMARY KEY (`id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
        """
        
        stmt = ParsedStatement(
            statement_type=StatementType.CREATE_TABLE,
            original_sql=sql,
            parsed_sql=None,
            table_name="users"
        )
        
        converted_stmt = self.converter._convert_create_table(stmt)
        converted_sql = converted_stmt.original_sql
        
        # 检查转换结果
        self.assertNotIn('`', converted_sql)
        self.assertNotIn('ENGINE=InnoDB', converted_sql)
        self.assertNotIn('DEFAULT CHARSET=utf8', converted_sql)
        self.assertIn('STRING', converted_sql)  # varchar -> STRING
        self.assertIn('BOOL', converted_sql)    # tinyint(1) -> BOOL
        self.assertIn('DEFAULT unique_rowid()', converted_sql)  # AUTO_INCREMENT
    
    def test_convert_insert_statement(self):
        """测试转换INSERT语句"""
        sql = "INSERT INTO `users` (`name`, `email`) VALUES ('John', 'john@example.com');"
        
        stmt = ParsedStatement(
            statement_type=StatementType.INSERT_INTO,
            original_sql=sql,
            parsed_sql=None,
            table_name="users"
        )
        
        converted_stmt = self.converter._convert_insert_into(stmt)
        converted_sql = converted_stmt.original_sql
        
        # 反引号应该被移除
        self.assertNotIn('`', converted_sql)
        self.assertIn('users', converted_sql)
        self.assertIn('name', converted_sql)
        self.assertIn('email', converted_sql)
    
    def test_convert_create_database_statement(self):
        """测试转换CREATE DATABASE语句"""
        sql = "CREATE DATABASE `test_db` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"
        
        stmt = ParsedStatement(
            statement_type=StatementType.CREATE_DATABASE,
            original_sql=sql,
            parsed_sql=None,
            database_name="test_db"
        )
        
        converted_stmt = self.converter._convert_create_database(stmt)
        converted_sql = converted_stmt.original_sql
        
        # MySQL特有的字符集设置应该被移除
        self.assertNotIn('DEFAULT CHARACTER SET', converted_sql)
        self.assertNotIn('COLLATE', converted_sql)
        self.assertNotIn('`', converted_sql)
        self.assertIn('test_db', converted_sql)
    
    def test_conversion_summary(self):
        """测试转换摘要"""
        original_statements = [
            ParsedStatement(StatementType.CREATE_TABLE, "CREATE TABLE test1 (id INT);", None),
            ParsedStatement(StatementType.CREATE_TABLE, "CREATE TABLE test2 (id INT);", None),
            ParsedStatement(StatementType.INSERT_INTO, "INSERT INTO test1 VALUES (1);", None),
        ]
        
        converted_statements = [
            ParsedStatement(StatementType.CREATE_TABLE, "CREATE TABLE test1 (id INT);", None),
            ParsedStatement(StatementType.CREATE_TABLE, "CREATE TABLE test2 (id INT);", None),
            ParsedStatement(StatementType.INSERT_INTO, "INSERT INTO test1 VALUES (1);", None),
        ]
        
        summary = self.converter.get_conversion_summary(original_statements, converted_statements)
        
        self.assertEqual(summary['total_original'], 3)
        self.assertEqual(summary['total_converted'], 3)
        self.assertEqual(summary['skipped'], 0)
        self.assertIn('by_type', summary)
    
    def test_custom_type_mapping(self):
        """测试自定义类型映射"""
        custom_config = {
            'type_mapping': {
                'BIGINT': 'BIGINT',  # 保持BIGINT不变
                'TEXT': 'LONGSTRING'  # 自定义映射
            }
        }
        
        converter = MySQLToKWDBConverter(custom_config)
        
        # 检查自定义映射是否生效
        self.assertEqual(converter.type_mapping['BIGINT'], 'BIGINT')
        self.assertEqual(converter.type_mapping['TEXT'], 'LONGSTRING')
        
        # 默认映射应该仍然存在
        self.assertEqual(converter.type_mapping['VARCHAR'], 'STRING')


if __name__ == '__main__':
    unittest.main()
